﻿using System;

namespace FpAgain.OOP {
  interface IVisitor {
    Visit(sum : VisitableTree.Sum) : void;
    Visit(sum : VisitableTree.Sin) : void;
    Visit(sum : VisitableTree.Variable) : void;
  }
  
  abstract class VisitableTree {
    public abstract AcceptVisitor(visitor : IVisitor) : void;
    
    public class Sum : VisitableTree {
      public mutable l : VisitableTree;
      public mutable r : VisitableTree;
      
      public override AcceptVisitor(visitor : IVisitor) : void {
        visitor.Visit(this);
      }
    }
    
    public class Sin : VisitableTree {
      public mutable op : VisitableTree;
      
      public override AcceptVisitor(visitor : IVisitor) : void {
        visitor.Visit(this);
      }
    }
    
    public class Variable : VisitableTree {
      public mutable name : string;
      
      public override AcceptVisitor(visitor : IVisitor) : void {
        visitor.Visit(this);
      }
    }
  }
}